package lambda;

/*
    lambda表达式的本质上就是接口的实现类的具体的对象
    使用lambda表达式：接口中只能有一个抽象方法，而且只有一个抽象方法的接口又称函数式接口
    所以一般在定义函数式接口的时候，都会加上@FunctionalInterface注解，来进行约束，就是当这个接口的抽象方法大于一个的时候，就会报错
 */
public class Controller {
    public static void main(String[] args) {

        // 执行myinterface接口中的testMethod的方法一：创建该接口的实现类，然后调用方法
        myinterfaceImpl myImple = new myinterfaceImpl();
        myImple.testMethod();

        // 执行myinterface接口中的testMethod的方法二：使用匿名内部类
        myinterface myinterface = new myinterface() {
            @Override
            public void testMethod() {
                System.out.println("我重写了接口里面的方法");
            }
        };

        myinterface.testMethod();

        // 执行myinterface接口中的testMethod的方法三：使用lambda表达式
        /*
        () -> System.out.println("我重写了接口里面的方法");
        中的 () 表示重写 myinterface接口中的testMethod()方法，这个是由方法参数来判断的，然后System.out.println("我重写了接口里面的方法")是重写的内容
          完整的书写方式应该为：() -> {System.out.println("我重写了接口里面的方法");}，但是重写的方法体里面如果只有一句话的话，那么花括号可以不用写
         */
        myinterface myinterface1 = () -> System.out.println("我重写了接口里面的方法");
        myinterface1.testMethod();

        System.out.println("********************************************");

        /*
            当接口中的参数为void test(int a); 时 参数类型可以不用写，然后当参数只有一个时，()也可以不用写，所以就直接 a -> System.out.println("a = " + a);
         */
        TestA testA = a -> System.out.println("a = " + a);
        testA.test(10);

        System.out.println("********************************************");
        // 有多个参数的时候，()不可以省略，结构体里面有多句话的时候，也不能把{}省略
        TestB testB = (a,b) ->{
            System.out.println("第一句话");
            System.out.println("第二句话");
            return a+b;
        };
        // TestB testb1 = (a,b) -> {return "a";}; 可以把return 跟{}都省略
        TestB testb1 = (a,b) -> "a";

        System.out.println(testB.testB("你好，","北京"));
        System.out.println(testb1.testB("a","b"));


    }
}
